package cn.yangliu.init;

import cn.yangliu.init.annotations.InitJob;
import cn.yangliu.init.config.InitProperties;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import lombok.Lombok;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * The type of package-scan.
 *
 * <p>
 * .
 *
 * @author 问道于盲
 * @date 2020 -04-16
 */
public class InitAnalysisEventListener extends AnalysisEventListener {

    /**
     * current class instance's member.
     * The InitHandler.
     */
    protected InitHandler handler;

    /**
     * current class instance's member.
     * The Data list.
     */
    protected List<Object> dataList = new ArrayList<>();

    @Override
    public void invoke(Object row, AnalysisContext analysisContext) {
        if (Objects.isNull(handler)) {
            InitJob job = row.getClass().getDeclaredAnnotation(InitJob.class);
            Class<? extends InitHandler> handlerClass = job.handler();
            handler = InitWorker.getApplicationContext().getBean(handlerClass);

        }
        /**
         * 数据转换
         */
        Object bean = this.handler.createBean(row);
        BeanUtils.copyProperties(row, bean);
        dataList.add(bean);

    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        if (CollectionUtils.isEmpty(dataList)) {
            return;
        }

        InitProperties properties = InitWorker.getApplicationContext().getBean(InitProperties.class);

        /**
         * 不开启事务
         */
        if (!properties.isTransactional()) {
            handler.persistAll(dataList);
            return;
        }

        /**
         * 开启事务处理数据
         */
        TransactionTemplate template = InitWorker.getApplicationContext().getBean(TransactionTemplate.class);

        template.execute(transactionStatus -> {
            try {
                handler.persistAll(dataList);
            } catch (Exception e) {
                transactionStatus.setRollbackOnly();
                throw Lombok.sneakyThrow(e);
            }
            return null;
        });

    }

}
